package cn.zuo.service;

import cn.zuo.pojo.Message;
import cn.zuo.pojo.User;
import cn.zuo.utils.*;
import com.alibaba.fastjson.JSON;

import javax.swing.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @Author 白白旧维
 * @Date 2021/7/7 11:13
 */
public class Check {

    private Socket s;
    private Message msg;
//    private String seed;


    private Map<String, BigInteger> key;

    public Map<String, BigInteger> getKey() {
        return key;
    }

    public Message getMsg() {
        return msg;
    }

    public Socket getS() {
        return s;
    }

    public boolean check(String username, String password) throws Exception {
        s = new Socket("127.0.0.1",9999);


        ObjectInputStream ois1 = new ObjectInputStream(s.getInputStream());

        //先接收服务端的公钥
        Message key_msg = (Message) ois1.readObject();
        BigInteger server_e = new BigInteger(key_msg.getMsg().split("_")[0]);
        BigInteger server_n = new BigInteger(key_msg.getMsg().split("_")[1]);
        PublicKeyPool.setServer_key_e(server_e);
        PublicKeyPool.setServer_key_n(server_n);
        System.out.println(server_e+"_"+server_n);

        //发送自己的公钥给服务端
        ObjectOutputStream oos1 = new ObjectOutputStream(s.getOutputStream());
        Map<String, BigInteger> key = PPKeyFactory.getOneKey(System.currentTimeMillis() + new Random().nextLong());
        BigInteger login_e = key.get("e");
        BigInteger login_n = key.get("n");
        oos1.writeObject(new Message(username,null,login_e+"_"+login_n));


        //加密和签名
        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
//        String password_hm = MD5.md5(password);//哈希
        String password_hm = SHA256.sha256(password);//哈希

        List<BigInteger> password_hm_signed = RSA.signed_mul(key.get("d"), key.get("n"), password_hm);
        String password_hm_signed_json = JSON.toJSONString(password_hm_signed);//签名

        String password_and_signed = password+"_"+password_hm_signed_json;//密码信息和签名合并

        List<BigInteger> en_password_and_signed = RSA.encryption_mul(PublicKeyPool.getServer_key_e(), PublicKeyPool.getServer_key_n(), password_and_signed);
        String en_password_and_signed_json = JSON.toJSONString(en_password_and_signed);//加密

        oos.writeObject(new Message(username,"login",en_password_and_signed_json));

        ObjectInputStream ois_userList = new ObjectInputStream(this.s.getInputStream());
        Message userList = (Message) ois_userList.readObject();


        if("-1".equals(userList.getMsg())){
            JOptionPane.showMessageDialog(null,"已有登录！！");
            return false;
        }else if("0".equals(userList.getMsg())){
            JOptionPane.showMessageDialog(null,"账号或密码错误！！");
            return false;
        }else{//登录成功就可以开始接收信息了
            System.out.println(userList.getReceiver()+"登录成功!!");
            //需要传递给UserMain的msg,关于用户列表的信息
            this.msg = userList;

            //新：发送CtoC公钥给服务端保存
            Map<String, BigInteger> cckey = PPKeyFactory.getOneKey(System.currentTimeMillis() + new Random().nextLong());
            System.out.println("新：发送CtoC公钥给服务端保存");
            Message cckey_msg = new Message(msg.getReceiver(),"server",cckey.get("e")+"_"+cckey.get("n"),"key");
            System.out.println(cckey_msg);//a、客户端CtoC公钥发送给服务端是否成功？？
            this.key = cckey;

            ObjectOutputStream oos_cckey_msg = new ObjectOutputStream(s.getOutputStream());
            oos_cckey_msg.writeObject(cckey_msg);



            //启动接收信息线程
            Receive receive = new Receive(this.s,msg.getReceiver(),key.get("d"),key.get("n"));
            receive.start();
//            this.seed = receive.getSeed();
//            System.out.println("check中的seed:"+this.seed);不使用这种保存seed，因为使用的是多线程模式就会导致大概率会为null
            //保存到AESRandomKey中


            return true;
        }

    }




}
